#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" Defines database connection middleware.

The component below currently provides on the minimum functionality.
Obvious areas of growth are (1) transaction support, (b) error
recovery.
"""
## TODO:  realistic transaction support

from tack.lib import copy_appattrs


def dbconnector(app, source_key, target_key, connect, dsn_lookup=None):
    """ Database connection middleware.

    This middleware creates a database connection based on the value
    of the source key found in the WSGI environment.  The newly
    created connection is stored back into the environment at the
    target key.

    Note that this middleware can be installed multiple times in a
    given WSGI application and only a single database connection will
    be created.

    @param app wrapped WSGI application
    @param source_key environment key that contains DSN
    @param target_key environment key to receive database connection
    @param connect call to create database connection, passed DSN
    @return new WSGI application
    """
    if not dsn_lookup:
        dsn_lookup = lambda env:env.pop(source_key, None)

    def inner(environ, start_response):
        if not environ.get(target_key):
            dsn = dsn_lookup(environ)
            if dsn:
                environ[target_key] = connect(dsn)
        return app(environ, start_response)
    return copy_appattrs(app, inner)


def dbconnector_exp(app, connect, dsn, target='connection'):
    def dbconnection(environ, start_response):
        if target not in environ:
            if callable(dsn):
                dsn = dsn(environ)
            if dsn:
                environ[target] = connect(dsn)
        return app(environ, start_response)
    return copy_appattrs(app, dbconnection)
